#include "class_bars.h"

class_bars::class_bars()
{
init();
}

void class_bars::init()
{
memset(&data,0, sizeof(struct_bar));
flag=0;
volume_old=0;
}

class_bars::~class_bars()
{
datas.clear();
}

//读入
int class_bars::read(std::string dz,int num)
{
	std::ifstream file(dz,std::ios::binary | std::ios::app);
	struct_bar bar={0};
if(!file.is_open())
{
	std::cout<<dz<<"打开失败"<<std::endl;
	return -1;
}

while(file.read(reinterpret_cast<char*>(&bar),sizeof(struct_bar)) )
	{
        datas.push_back(bar);
	}
file.close();

	return datas.size();
}

//读入tick
int class_bars::read_tick(std::string dz,int num)
{
	std::ifstream file(dz,std::ios::binary | std::ios::app);
	struct_tick tick={0,0,0,0,0,0,0,0,"",""};
if(!file.is_open())
{
	std::cout<<dz<<"打开失败"<<std::endl;
	return -1;
}

while(file.read(reinterpret_cast<char*>(&tick),sizeof(struct_tick)) )
	{
if(file.fail() )
{
file.clear();
std::cout<<dz<<"读取失败"<<std::endl;
break;
}

if(tick.UpdateTime[2] != ':' || tick.UpdateTime[5] != ':' )
{
file.seekg(file.tellg() - static_cast<std::streamoff>(sizeof(struct_tick) - 1));
continue;
}

CThostFtdcDepthMarketDataField hq;
memset(&hq,0,sizeof(CThostFtdcDepthMarketDataField) );
hq.LastPrice=tick.LastPrice;
hq.BidPrice1=tick.BidPrice1;
hq.AskPrice1=tick.AskPrice1;
hq.OpenInterest=tick.OpenInterest;
hq.Volume=tick.Volume;
hq.BidVolume1=tick.BidVolume1;
hq.AskVolume1=tick.AskVolume1;
hq.UpdateMillisec=tick.UpdateMillisec;
strncpy(hq.TradingDay,tick.TradingDay, sizeof(tick.TradingDay));
strncpy(hq.UpdateTime,tick.UpdateTime, sizeof(tick.UpdateTime));
		insert(hq);
	}
file.clear();
file.close();

	return datas.size();
}


//读入文本类型
int class_bars::read_txt(std::string dz,int num)
{
	std::ifstream file(dz);
if(!file.is_open())
{
	std::cout<<dz<<"打开失败"<<std::endl;
	return -1;
}

std::string line;
while(std::getline(file,line) )
{
	std::istringstream xx(line);
struct_bar bar={0};
if(!(xx>> bar.date>>bar.time>>bar.o>>bar.h>>bar.l>>bar.c>>bar.volume>>bar.open_interest) )
{
	std::cout<<line<<"解析失败"<<std::endl;
	return -1;
}
datas.push_back(bar);
}
file.close();
return datas.size();
}


//写出
int class_bars::write(std::string dz,int num)
{
if(datas.size() == 0 && flag == 0)
{
	return 0;
}
	std::ofstream file(dz,std::ios::binary | std::ios::app);
if(!file.is_open())
{
	std::cout<<dz<<"打开失败"<<std::endl;
return -1;
}

for(auto it=datas.begin(); it != datas.end(); ++it)
{
file.write(reinterpret_cast<const char*>(&(*it)),sizeof(struct_bar));
}
if(flag == 1)
{
file.write(reinterpret_cast<const char*>(&data),sizeof(struct_bar));
init();
}
file.close();
	return datas.size();
}


//写出文本类型
int class_bars::write_txt(std::string dz,int num)
{
if(datas.size() == 0 && flag == 0)
{
	return 0;
}
	std::ofstream file(dz,std::ios::app);
if(!file.is_open())
{
	std::cout<<dz<<"打开失败"<<std::endl;
	return -1;
}

for(auto it = datas.begin(); it !=datas.end(); ++it)
{
file<<it->date<<" "<<it->time<<" "<<it->o<<" "<<it->h<<" "<<it->l<<" "<<it->c<<" "<<it->volume<<" "<<it->open_interest<<std::endl;
}
if(flag == 1)
{
file<<data.date<<" "<<data.time<<" "<<data.o<<" "<<data.h<<" "<<data.l<<" "<<data.c<<" "<<data.volume<<" "<<data.open_interest<<std::endl;
class_bars();
}
file.close();
	return datas.size();
}

//插入tick
int class_bars::insert(CThostFtdcDepthMarketDataField &tick)
{
if(data.time[4] != tick.UpdateTime[4] || data.time[3] != tick.UpdateTime[3] || data.time[1] != tick.UpdateTime[1] || data.time[0] != tick.UpdateTime[0] || flag == 0)
{
if(flag == 1)
{
	datas.push_back(data);
}
flag=1;
data.o=tick.LastPrice;
data.h=tick.LastPrice;
data.l=tick.LastPrice;
data.c=tick.LastPrice;
data.open_interest=tick.OpenInterest;

if(tick.Volume >= volume_old)
{
data.volume=tick.Volume - volume_old;;
}
else
{
data.volume=tick.Volume;
}
volume_old=tick.Volume;
std::copy(tick.TradingDay,tick.TradingDay + 9,data.date);
std::copy(tick.UpdateTime,tick.UpdateTime + 5,data.time);
}

if(tick.LastPrice > data.h)
{
data.h=tick.LastPrice;
}
if(tick.LastPrice < data.l)
{
data.l=tick.LastPrice;
}
data.c=tick.LastPrice;
data.open_interest=tick.OpenInterest;
data.volume+=(tick.Volume - volume_old);
volume_old=tick.Volume;
return 0;
}


//平均值
double class_bars::average(int b, int e)
{
if(e > datas.size())
{
	return data.c;
}
	return std::accumulate(datas.rbegin()+b,datas.rbegin()+e, 0.0, [](double a, struct_bar &d){return a+d.c;})/(e-b);
}


//获取最高
double class_bars::highest(int b,int e)
{
if(e > datas.size() )
{
	return data.h;
}
	return max_element(datas.rbegin()+b, datas.rbegin()+e, [](const struct_bar &a, const struct_bar &d){return a.h < d.h;})->h;
}


//获取最低
double class_bars::lowest(int b,int e)
{
if(e > datas.size() )
{
	return data.l;
}
	return min_element(datas.rbegin()+b, datas.rbegin()+e, [](const struct_bar &a, const struct_bar &d){return a.l < d.l;})->l;
}


//标准差
double class_bars::sigma(int b,int e)
{
double z=0;
	if(datas.size() < e || b < 0){return 0;} 
std::vector<double> results(e-b);
std::transform(datas.rbegin()+b,datas.rbegin()+e,results.begin(), [](struct_bar &bar) -> double {return bar.c;});
z=std::accumulate(results.begin(),results.end(),0.0)/results.size();
for(auto &result:results)
{
result-=z;
result=result*result;
}
z=std::sqrt(std::accumulate(results.begin(),results.end(),0.0)/results.size());
return z;
}


//波动率
double class_bars::bdl(int b,int e, int ts)
{
double z=0.0;
	if(datas.size() < e || b < 0){return 0;} 
std::vector<double> results(e - b - 1);

for(auto it = datas.end() - e; it != datas.end() - b; ++it)
{
results.push_back(std::log(it->c / (it-1)->c) );
}
double ma = std::accumulate(results.begin(), results.end(),0.0) / results.size();
for(int i=0; i<results.size(); ++i)
{
results[i] = std::pow(results[i] - ma, 2);
}
double zz = std::sqrt(std::accumulate(results.begin(), results.end(), 0.0) / results.size() );
double bdl = zz * std::sqrt(ts * 252);
return bdl;
}
